#include "warehouseservice.h"
#include "constant/DBTableConfig.h"
#include "util/database/sqlgenerator.h"
#include "util/database/databasemanager.h"
#include <QSqlQuery>
#include <QDebug>

using namespace DBTableConfig;

/**
 * @brief 构造函数：初始化仓库服务
 * 初始化数据库连接相关的准备工作
 */
WarehouseService::WarehouseService()
{
    // 初始化操作可在此处添加
}

/**
 * @brief 查询所有仓库及关联的货架信息
 * 调用条件查询方法，传入空条件以获取全部数据
 * @param errorMsg 输出参数，用于返回错误信息
 * @return 包含所有仓库及其货架的VO对象列表
 */
QList<WarehouseVO> WarehouseService::getAllShelves(QString* errorMsg)
{
    return getShelvesByCondition(QMap<QString, QVariant>(), errorMsg);
}

/**
 * @brief 按条件查询仓库及关联的货架信息
 * 支持按仓库ID、仓库名称、货架ID、货架名称进行组合查询
 * @param conditions 查询条件键值对，支持的键包括：
 *        - warehouse_id: 仓库ID（int）
 *        - warehouse_name: 仓库名称（ QString，支持模糊查询）
 *        - shelf_id: 货架ID（int）
 *        - shelf_name: 货架名称（QString，支持模糊查询）
 * @param errorMsg 输出参数，用于返回错误信息
 * @return 符合条件的仓库VO对象列表，每个对象包含其关联的货架列表
 */
QList<WarehouseVO> WarehouseService::getShelvesByCondition(const QMap<QString, QVariant>& conditions,
                                                         QString* errorMsg)
{
    // 检查数据库连接状态
    if (!DatabaseManager::getInstance()->isConnected()) {
        if (errorMsg) *errorMsg = "数据库未连接";
        return {};
    }

    // 构建查询表（仓库表与货架表内连接）
    QString tableName = QString("%1 JOIN %2 ON %1.id = %2.warehouse_id")
        .arg(WAREHOUSE_TABLE, SHELF_TABLE);

    // 定义需要查询的字段，使用别名避免冲突
    QStringList fields = {
        QString("%1.id AS warehouse_id").arg(WAREHOUSE_TABLE),
        QString("%1.name AS warehouse_name").arg(WAREHOUSE_TABLE),
        QString("%1.quantity AS warehouse_quantity").arg(WAREHOUSE_TABLE),
        QString("%1.id AS shelf_id").arg(SHELF_TABLE),
        QString("%1.name AS shelf_name").arg(SHELF_TABLE),
        QString("%1.quantity AS shelf_quantity").arg(SHELF_TABLE),
        QString("%1.create_time AS shelf_create_time").arg(SHELF_TABLE),
        QString("%1.update_time AS shelf_update_time").arg(SHELF_TABLE)
    };

    // 构建查询条件
    QString condition;
    if (!conditions.isEmpty()) {
        QStringList whereClauses;

        if (conditions.contains("warehouse_id")) {
            whereClauses.append(QString("%1.id = %2")
                .arg(WAREHOUSE_TABLE).arg(conditions["warehouse_id"].toInt()));
        }
        if (conditions.contains("warehouse_name")) {
            whereClauses.append(QString("%1.name LIKE '%%2%'")
                .arg(WAREHOUSE_TABLE, conditions["warehouse_name"].toString()));
        }
        if (conditions.contains("shelf_id")) {
            whereClauses.append(QString("%1.id = %2")
                .arg(SHELF_TABLE).arg(conditions["shelf_id"].toInt()));
        }
        if (conditions.contains("shelf_name")) {
            whereClauses.append(QString("%1.name LIKE '%%2%'")
                .arg(SHELF_TABLE, conditions["shelf_name"].toString()));
        }

        condition = whereClauses.join(" AND ");
    }

    // 生成并执行查询SQL
    QString selectSql = SqlGenerator::generateSelect(tableName, fields, condition);
    if (selectSql.isEmpty()) {
        if (errorMsg) *errorMsg = "生成查询SQL失败";
        return {};
    }

    QSqlQuery query = DatabaseManager::getInstance()->executeQuery(selectSql, errorMsg);
    return queryToWarehouseVOList(query);
}

/**
 * @brief 将数据库查询结果转换为WarehouseVO列表
 * 处理仓库与货架的一对多关系，将同一仓库的多个货架聚合到对应的VO对象中
 * @param query 数据库查询结果集
 * @return 转换后的WarehouseVO对象列表，每个对象包含完整的仓库信息和关联的货架列表
 */
QList<WarehouseVO> WarehouseService::queryToWarehouseVOList(QSqlQuery& query)
{
    QList<WarehouseVO> resultList;
    QHash<int, WarehouseVO*> warehouseMap; // 以仓库ID为键，临时存储仓库对象

    while (query.next()) {
        int warehouseId = query.value("warehouse_id").toInt();

        // 若仓库不存在则创建新的仓库VO对象
        if (!warehouseMap.contains(warehouseId)) {
            WarehouseVO* newWarehouse = new WarehouseVO();
            newWarehouse->setWarehouseId(warehouseId);
            newWarehouse->setWarehouseName(query.value("warehouse_name").toString());
            newWarehouse->setWarehouseQuantity(query.value("warehouse_quantity").toInt());
            warehouseMap[warehouseId] = newWarehouse;
        }

        // 创建货架对象并添加到对应的仓库
        WarehouseVO* currentWarehouse = warehouseMap[warehouseId];
        Shelf shelf;
        shelf.set_id(query.value("shelf_id").toInt());
        shelf.set_warehouse_id(warehouseId);
        shelf.set_shelf_name(query.value("shelf_name").toString());
        shelf.set_shelf_quantity(query.value("shelf_quantity").toInt());
        shelf.set_create_time(query.value("shelf_create_time").toDateTime());
        shelf.set_update_time(query.value("shelf_update_time").toDateTime());

        currentWarehouse->addShelf(shelf);
    }

    // 将临时存储的仓库对象转移到结果列表并释放内存
    for (auto warehouse : warehouseMap) {
        resultList.append(*warehouse);
        delete warehouse;
    }

    return resultList;
}
